
import { Node, Color } from "cc"
import { Singleton } from "../framework/base/Singleton"
import { IGameData } from "../src/shared/common/Interface"
import { RenderData } from "./RenderData"
import { ObjectPoolManager } from "../framework/ObjectPoolManager"
import { enemyEntity } from "../entity/Enemy/enemyEntity"
import { EArea, EEntity } from "../src/shared/common/Enum"
import { numberEntity } from "../entity/number/numberEntity"
import { towerEntity } from "../entity/Tower/towerEntity"
import { LayerManager } from "../framework/LayerManager"
/** 渲染管理 */
export class RenderManager extends Singleton {

    /** 当前回合 */
    curRound = 0
    /** 飘字区域 */
    numbersArea: Node
    /** 怪物区域 */
    enemyArea: Node
    /** 塔区域 */
    towerArea: Node
    /** 生命条区域 */
    barArea: Node
    /** 引擎区域 */
    shadowArea: Node
    /** 游戏数据 */
    gameData: IGameData

    area: EArea
    public static get Ins() {
        return this.GetInstance<RenderManager>()
    }

    render(gameData: IGameData, area: EArea) {
        this.gameData = gameData
        this.area = area
        this.fixPosY()
        this.renderEnemy()
        this.renderTower()
        this.setSibling()
        this.showRound()
    }

    /** 渲染怪物 */
    renderEnemy() {
        for (const enemy of this.gameData.enemies) {
            const { id, entityType } = enemy
            let ee = RenderData.Ins.enemy2id[id]
            if (!ee) {
                const node = ObjectPoolManager.Ins.poolAlloc(entityType)
                ee = node.getComponent(enemyEntity)
                if (!ee) {
                    node.parent = this.enemyArea
                    ee = node.addComponent(enemyEntity)
                    ee.init(enemy)
                }
                ee.reset(enemy)
                RenderData.Ins.enemy2id[id] = ee
            }
            ee.render(enemy)
        }

    }

    /** 渲染塔 */
    renderTower() {
        for (const tower of this.gameData.towers) {
            const { id, entityType } = tower
            let te = RenderData.Ins.tower2id[id]
            if (!te) {
                const node = ObjectPoolManager.Ins.poolAlloc(entityType)
                te = node.getComponent(towerEntity)
                if (!te) {
                    node.parent = this.towerArea
                    te = node.addComponent(towerEntity)
                    te.init(tower)
                }
                te.reset(tower)
                RenderData.Ins.tower2id[id] = te
            }
            te.render(tower)
        }
    }

    /** 伤害飘字 */
    showDmgNumber(dmg: number, x: number, y: number, isCrit: 0 | 1 = 0) {
        if (isCrit) {
            //todo
        } else {
            this.showLab(dmg, x, y)
        }
    }

    /** 我来了飘字 */
    showBornLab(x: number, y: number) {
        this.showLab('+', x, y, Color.RED, 100)
    }

    /** 飘字 */
    private showLab(dmg: number | string, x: number, y: number, color = Color.WHITE, fontSize = 40) {
        const node = ObjectPoolManager.Ins.poolAlloc(EEntity.battleNumber)
        let nm = node.getComponent(numberEntity)
        if (!nm) {
            node.parent = this.numbersArea
            nm = node.addComponent(numberEntity)
            nm.init(EEntity.battleNumber)
        }
        nm.render(color, dmg, x, y, fontSize)
    }

    /** 通过id获取防御塔坐标 */
    getTowerPosById(ox: number, oy: number, oid: number) {
        let towerNum = 0
        let index = 0
        for (const tower of this.gameData.towers) {
            const { x, y, id } = tower
            if (x == ox && y == oy) {
                ++towerNum
                if (oid == id) index = towerNum
                if (towerNum >= 3) break
            }
        }

        const action = {
            1: {
                1: { x: ox, y: oy },
            },
            2: {
                1: { x: ox + 15, y: oy + 15 },
                2: { x: ox - 15, y: oy },
            },
            3: {
                1: { x: ox - 15, y: oy + 30 },
                2: { x: ox + 15, y: oy + 15 },
                3: { x: ox - 15, y: oy },
            }
        }
        return action[towerNum][index]
    }

    /** 排序频率 */
    private siblingRate = 0
    /** 怪物层级排序 */
    setSibling() {
        ++this.siblingRate
        if (this.siblingRate < 40) return
        this.siblingRate = 0
        this.sibling(this.towerArea)
        this.sibling(this.enemyArea)
    }

    sibling(parent: Node) {
        const siblings = parent.children
        if (siblings) {
            const temp = {}
            for (const node of siblings) {
                const index = 100000 - Math.round(node.getPosition().y * 100)
                if (!temp[index]) temp[index] = []
                temp[index].push(node)
            }
            parent.removeAllChildren()
            for (const key in temp) {
                const arr: Node[] = temp[key]
                for (const node of arr) {
                    node.parent = parent
                    if (node.getPosition().y > -100) {
                        node.active = true
                    }
                }
            }
        }
    }

    /** 根据用户修正怪物Y坐标 */
    fixPosY() {

        if (this.area == EArea.up) {

            for (const enemy of this.gameData.enemies) {
                enemy.y = -enemy.y
            }
            for (const tower of this.gameData.towers) {
                tower.y = -tower.y
            }

        }

    }

    /** 回合展示 */
    showRound() {
        if (this.curRound != this.gameData.levelData.curRound) {
            this.curRound = this.gameData.levelData.curRound
            LayerManager.Ins.toast('回合:' + this.curRound)
        }
    }

}